package POS;

//import javax.ejb.EJB;
import javax.ejb.Stateless;

import javax.ws.rs.Path;
import javax.ws.rs.GET;
//import javax.ws.rs.PUT;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
//import javax.ws.rs.Consumes;
//import javax.ws.rs.PathParam;
//import javax.ws.rs.FormParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.DefaultValue;

import java.io.*;

import org.w3c.dom.*;

import javax.xml.parsers.*;

import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

/**
 * REST Web Service
 *
 * @author bogdan
 */

@Stateless
@Path("/POS")
public class POSResource {

    @GET
    @Path("/getmessages")
    @Produces("text/xml")
    public String getMessages(
            @DefaultValue("") @QueryParam("userId") String userId,
            @DefaultValue("inbox") @QueryParam("folder") String folder
            )
    {
        String xmlString = "";
        File userDir = new File("C:\\POS\\" + userId);

        // Check if the folder exists
        if (!userDir.exists() || userId.isEmpty())
        {
            System.out.println("ERROR: user not found: " + userId);
            return "<error>User not found: " + userId + "</error>";
        }

        userDir = new File("C:\\POS\\" + userId + "\\" + folder);
        if (!userDir.exists())
        {
            System.out.println("ERROR: folder not found: " + userDir.getPath());
            return "<error>Folder not found: " + userDir.getPath() + "</error>";
        }

        try {
            /////////////////////////////
            //Creating an empty XML Document

            //We need a Document
            DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
            Document doc = docBuilder.newDocument();

            ////////////////////////
            //Creating the XML tree

            //create the root element and add it to the document
            Element messagesElement = doc.createElement("messages");
            doc.appendChild(messagesElement);

            FilenameFilter filter = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return !name.endsWith(".xml");
                }
            };

            String[] children = userDir.list();
            if (children == null) {
                // Either dir does not exist or is not a directory
            } else {
                for (int i = 0; i < children.length; i++) {
                    // Get filename of file or directory
                    String filename = children[i];

                    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                    dbf.setValidating(false);

                    DocumentBuilder db = dbf.newDocumentBuilder();
                    Document xmlFile = db.parse(
                            new File("C:\\POS\\" + userId + "\\" + folder + "\\" + filename)
                            );
                    xmlFile.getDocumentElement().normalize();

                    NodeList nodeLst;

                    if (folder.equals("inbox"))
                        nodeLst = xmlFile.getElementsByTagName("to");
                    else //if (folder.equals("sent"))
                        nodeLst = xmlFile.getElementsByTagName("from");
                    if (nodeLst.getLength() != 1)
                        continue;
                    if (!nodeLst.item(0).getTextContent().equals(userId))
                        continue;

                    Element messageElement = doc.createElement("message");
                    messagesElement.appendChild(messageElement);

                    if (folder.equals("inbox"))
                    {
                        nodeLst = xmlFile.getElementsByTagName("from");
                        if (nodeLst.getLength() != 1)
                            continue;

                        Element fromElement = doc.createElement("from");
                        messageElement.appendChild(fromElement);
                        fromElement.appendChild(doc.createTextNode(nodeLst.item(0).getTextContent()));
                    }
                    else //if (folder.equals("sent"))
                    {
                        nodeLst = xmlFile.getElementsByTagName("to");
                        if (nodeLst.getLength() != 1)
                            continue;

                        Element toElement = doc.createElement("to");
                        messageElement.appendChild(toElement);
                        toElement.appendChild(doc.createTextNode(nodeLst.item(0).getTextContent()));
                    }
                    

                    nodeLst = xmlFile.getElementsByTagName("subject");
                    if (nodeLst.getLength() != 1)
                        continue;

                    Element subjectElement = doc.createElement("subject");
                    messageElement.appendChild(subjectElement);
                    subjectElement.appendChild(doc.createTextNode(nodeLst.item(0).getTextContent()));

                    nodeLst = xmlFile.getElementsByTagName("date");
                    if (nodeLst.getLength() != 1)
                        continue;

                    Element dateElement = doc.createElement("date");
                    messageElement.appendChild(dateElement);
                    dateElement.appendChild(doc.createTextNode(nodeLst.item(0).getTextContent()));

                }
            }

            /////////////////
            //Output the XML

            //set up a transformer
            TransformerFactory transfac = TransformerFactory.newInstance();
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");

            //create string from xml tree
            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            DOMSource source = new DOMSource(doc);
            trans.transform(source, result);
            xmlString = sw.toString();

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
                
        return xmlString;
    }

    @GET
    @Path("/getmessage")
    @Produces("text/xml")
    public String getMessage(
            @DefaultValue("") @QueryParam("userId") String userId,
            @DefaultValue("inbox") @QueryParam("folder") String folder,
            @DefaultValue("") @QueryParam("date") String date
            )
    {
        String xmlString = "";
        File userDir = new File("C:\\POS\\" + userId);

        // Check if the folder exists
        if (!userDir.exists() || userId.isEmpty())
        {
            System.out.println("ERROR: user not found: " + userId);
            return "<error>User not found: " + userId + "</error>";
        }

        userDir = new File("C:\\POS\\" + userId + "\\" + folder);
        if (!userDir.exists())
        {
            System.out.println("ERROR: folder not found: " + userDir.getPath());
            return "<error>Folder not found: " + userDir.getPath() + "</error>";
        }

        File xmlFile = new File(
                userDir.getPath() +
                "\\" +
                date.replace(' ', '_').replace(':', '-') +
                ".xml");
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        DataInputStream dis = null;

        try {
            fis = new FileInputStream(xmlFile);

            // Here BufferedInputStream is added for fast reading.
            bis = new BufferedInputStream(fis);
            dis = new DataInputStream(bis);

            // dis.available() returns 0 if the file does not have more lines.
            while (dis.available() != 0) {
                xmlString += dis.readLine();
            }

            // dispose all the resources after using them.
            fis.close();
            bis.close();
            dis.close();

        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
        
        return xmlString;
    }

    @POST
    @Path("/sendmessage")
    @Produces("text/xml")
    public String sendMessage(
            @DefaultValue("") @QueryParam("from") String from,
            @DefaultValue("") @QueryParam("to") String to,
            @DefaultValue("") @QueryParam("subject") String subject,
            @DefaultValue("") @QueryParam("message") String message
            )
    {
        String xmlString = "<success>Message successfuly sent.</success>";
        MessageStorageBean messageStorage = new MessageStorageBean();

        if (from.isEmpty())
        {
            System.out.println("ERROR: no sender specified.");
            return "<error>No sender specified.</error>";
        }
        if (to.isEmpty())
        {
            System.out.println("ERROR: no recipient specified.");
            return "<error>No recipient specified.</error>";
        }
        // Check if the folder exists
        File userDir = new File("C:\\POS\\" + from);
        if (!userDir.exists())
        {
            System.out.println("ERROR: sender not found: " + from);
            return "<error>Sender not found: " + from + "</error>";
        }
        userDir = new File("C:\\POS\\" + to);
        if (!userDir.exists())
        {
            System.out.println("ERROR: recipient not found: " + to);
            return "<error>Recipient not found: " + to + "</error>";
        }

        messageStorage.setFrom(from);
        messageStorage.setTo(to);
        messageStorage.setDate(DateUtils.now());
        if (!subject.isEmpty())
            messageStorage.setSubject(subject);
        if (!message.isEmpty())
            messageStorage.setBody(message);
        messageStorage.saveMessage(DateUtils.generateFileName(), true);

        return xmlString;
    }

//    @POST
//    @Consumes("application/x-www-form-urlencoded")
//    public String post(@FormParam("userId") String userId) {
//        return userId;
//    }


    /**
     * PUT method for updating an instance of POSResource
     * @param content representation for the resource
     * @return an HTTP response with content of the updated or created resource.
     */
//    @PUT
//    @Consumes("text/plain")
//    public void putXml(String content) {
//        messageStorage.setName(content);
//    }
}
